今天要來時做一個很酷的功能就是用 trpc
實作無限滾動~~~拍手,內容主要分兩部份
要製作無限滾動沒有大量的資料怎麼叫做無限滾動呢!!,這邊會介紹後端開發中會用到的小技巧就是 seed data
,沒有想過如果今天開發 api
沒有資料可以測試難不成每次都要一個一個自己家嗎?那這樣效果也太慢了,或是 migrate db
schema
時候都會被清空資料,這樣每次都要重新新增是不是很麻煩,於是就有 seed data
概念,如果新手不會沒關係這邊 Danny
會手把手教會你~
想要有良好的無限滾動勢必也要有很好的 query
工具,這邊會一一介紹 useInfiniteQuery
的實作與背後怎麼運行,不再對無限滾動的 client
邏輯困惑~
seed
有一個很概念叫 seeder
,seeder
有時候我們可能需要做 test
會用到 db
資料,這時為了確保每次執行 test
用到的資料都會是固定的,就會寫一個 seed script
在跑 test
前把固定的test
資料存到 db
中,如此一來每次跑 test
的資料才會是準確的。
還有就是假如我們 db modal
需要做 migrate
,這時會了確保資料準確性,會先把資料從 db
中全部清除,這時就可以透過 seed data
把一些基本資料先寫入,如此一來也方便後端開發。
首先先 install
> npm install @faker-js/faker --save-dev
因會我們會需要新增一些假資料,Faker
這個套件很方便是可以自動幫你隨機生成你要的資料格式,提供的種類非常多,例如貨幣、文本、個人資料等等。
使用方式非常簡單例如我需要生成 email
資料跟 fullName
import { faker } from '@faker-js/faker';
// or, if desiring a different locale
// import { fakerDE as faker } from '@faker-js/faker';
const randomName = faker.person.fullName(); // Rowan Nikolaus
const randomEmail = faker.internet.email(); // Kassandra.Haley@erich.biz
甚至如果你考慮到語系問題,沒關係 faker
也幫你準備好了,你只需要在 import
地方根據你想用到的語系引入就 ok
。
import { faker } from '@faker-js/faker/locale/de';
相關連結: https://fakerjs.dev/
因為我們要跑 seed
所以等下會寫一個 script
去跑,那因為我們是在 node
環境,大部分會是用 node
、 ts-node
、 nodemon
去執行,但有時候會因為 module
跟 commonjs
package type
問題,讓你無法執行 script
,但 tsx
同時兼容兩者的 type
所以用起來靈活度很高,就不用一直調整 package type
,同時他也支援 ts
~
> npm install --save-dev tsx
// package.json
{
"scripts": {
"dev": "tsx ..."
}
}
相關連結 : https://www.npmjs.com/package/tsx
首先我們新增 prisma/seed.ts
// ~prisma/seed.ts
import { prisma } from "@/server/db"
import { faker } from '@faker-js/faker';
let PostsCount = 100
const main = async () => {
try {
await prisma.post.deleteMany({})
const Posts = new Array(PostsCount).fill('_').map(() => prisma.post.create({
data: {
title: faker.lorem.slug(),
content: faker.lorem.paragraph({ max: 3, min: 1 }),
published: faker.datatype.boolean(0.5)
}
}))
await prisma.$transaction(Posts)
console.log('success add post data')
} catch (e) {
console.log(e)
}
}
main()
.finally(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.log(e)
await prisma.$disconnect()
process.exit(-1)
})
每次都刪除 post
資料,確保每次執行 seed
的結果都是固定 100 筆,否則每次執行 seed
後都會一直加資料,這可以減少 db
負擔。
await prisma.post.deleteMany({})
透過 transaction
方式會比用迴圈一個一個 create
來說效率來得高,而且 transaction
也可以保證 100 筆資料是正確 insert
的,會這麼說是因為 transaction
特性,要馬全部成功要馬全部失敗,如果用迴圈你無法確保每次 create
都是成功的。
const Posts = new Array(PostsCount).fill('_').map(() => prisma.post.create({
data: {
title: faker.lorem.slug(),
// 最少 1 個文章段落,最多三段
content: faker.lorem.paragraph({ max: 3, min: 1 }),
// true 或是 faqlse 機率都是 0.5
published: faker.datatype.boolean(0.5)
}
}))
await prisma.$transaction(Posts)
這邊要記得 seed 後要 $disconnect, 確保 connection pool
不是因為 seed 而佔用了,process.exit(-1)
則是只要有 error 就結束執行 script 。
main()
.finally(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.log(e)
await prisma.$disconnect()
process.exit(-1)
})
那 prisma
怎麼執行 seed script
,其實很簡單, prisma
很貼心的有整合到 package.json
中,你只需要添加 seed
keywoard 後面放你要執行的內容,以我們例子來說,我希望透過 tsx
幫我執行 prisma/seed.ts
這個檔案我會這麼寫:
// package.json
"prisma": {
"seed": "tsx prisma/seed.ts"
}
這時就可以測試 seed
功能拉~
在你的 terminal
中打以下 cli
> npx prisma db seed
如果你看到以下內容恭喜你成功 seed data 拉
../
Environment variables loaded from .env
Running seed command `tsx prisma/seed.ts` ...
success add post data
🌱 The seed command has been executed.
最後我們看一下 studio
> npx prisma studio
成功添加資料了 ~
這樣我們就完成無限滾輪的資料部分了~明天接著介紹怎麼寫 api 以及前端怎麼接~
https://www.npmjs.com/package/tsx
https://github.com/Danny101201/next_demo/tree/main
✅ 前端社群 :
https://lihi3.cc/kBe0Y